#include <iostream>

/*主要问题在于：执行析构函数时，子类对象调用的是父类的析构函数，导致子类对象无法正确释放资源。*/
/*1、需要将父类析构函数设置为虚函数，子类对象调用的是子类的析构函数，子类对象释放资源时，会先调用子类的析构函数，再调用父类的析构函数。*/
/*2、不能将普通的析构函数设置为虚函数，因为这样会增大类的大小，增加运行时间，降低效率。*/


class Test 
{
    public:
        Test(){};
         ~Test(){std::cout << "Test::~Test()" << std::endl;};

         /*
         欲实现出 virtual 函数，对象必须携带某些信息，主要用来在运行期决定哪一个virtual函数该被调用。
         这份信息通常是由一个所谓vptr(virtual table pointer)指针指出。
         vptr 指向一个由函数指针构成的数组,称为vtbl(virtualtable);
         每一个带有 virtual函数的 class 都有一个相应的 vtbl。
         当对象调用某virtual函数，实际被调用的函数取决于该对象的 vptr 所指的那编译器在其中寻找适当的函数指针。*/
         //virtual ~Test(){std::cout << "Test::~Test()" << std::endl;};
};


class Base  //polymorphic base class    多态基类
{   
    public:
        Base(){};
        virtual~Base(){std::cout << "Base::~Base()" << std::endl;};
        void print(){std::cout << "Base::print()" << std::endl;};//父类强制实现
        virtual void print1(){std::cout << "Base::print1()" << std::endl;};//父类默认实现
        virtual void print2()=0;//父类强制子类实现纯虚函数

};


class Derived : public Base 

{

    public:
        Derived(){};
        ~Derived(){std::cout << "Derived::~Derived()" << std::endl;};//先调用子类的析构函数，再调用父类的析构函数
        void print2(){std::cout << "Derived::print2()" << std::endl;};//子类实现纯虚函数
        void print1(){std::cout << "Derived::print()" << std::endl;};//子类重写父类虚函数  自身优先级高于父类
};

int main() 
{
    Base *b = new Derived();
    b->print1();
    b->print2();

    std::cout << "sizeof(Test) = "<<sizeof(Test) << std::endl;

    delete b;
}